import angular from 'angular';
import videojs from 'video.js';
import 'progressbar.js';
import 'fluxSlider';
/**
 * zhx.media.review Controller
 * Author: Vicco Wang
 * Date: 2017/10/18
 * Version : 1.0.0
 *
 */

angular.module('zhx.media.review').controller('zhxMediaReviewController',
    ['$scope','$element','$q','$timeout','$interval','zhxMediaReview.service', ($scope,$element,$q,$timeout,$interval,zhxMediaReviewService)=>{
        //获取原始数据的promise对象
        let GetCurrentData = $q.defer();
        //从服务中复制出来的一份播放列表
        let PlaybackList = [];
        //当前播放对象的ID
        // let PlaybackId = null;
        //当前播放对象的Area
        let PlayArea = null;
        //播放进度对象
        let PlayPercent = null;
        //播放完毕状态
        $scope.playEnd = false;

        /**
         * 构建模板,播放区域
         * @param data
         * @returns {Promise}
         * @private
         */
        const _constructTemplateInPage = (data) => {
            let tplDeffred = $q.defer();
            const tplData = data.template;
            $scope.baseTemplate = tplData.url;
            $element.css({
                backgroundImage : `url(${$scope.baseTemplate})`,
                backgroundRepeat : 'no-repeat',
                backgroundSize : '100%'
            });
            //播放区域DOM
            const playArea = PlayArea = angular.element(`<div class="zhx-play-area"></div>`);
            //上层放一个美化的MASK,添加一些阴影效果
            const playAreaMsk = angular.element(`<div class="zhx-play-mask"></div>`);
            //放一个播放对象播放进度控件层;
            const playController = angular.element(`<div class="zhx-play-percent" id="zhxMediaReviewPercent"></div>`);
            //获取当前比率,该比率目前以1920*1080分辨率配置;
            const screenRatio = parseFloat($scope.baseRatio);
            //获取播放区域根据比率计算的实际大小
            const areaStyle = {
                width   : tplData.size[0] / screenRatio,
                height  : tplData.size[1] / screenRatio,
                left    : tplData.position[0] / screenRatio,
                top     : tplData.position[1] / screenRatio
            };
            //配置样式
            angular.element(playArea,playAreaMsk).css(areaStyle);
            //添加进DOM树
            playArea.append(playController);
            $element.append([playAreaMsk,playArea]);
            tplDeffred.resolve(tplData);
            return tplDeffred.promise;
        };

        /**
         * 通过ID来查找playerList当中的播放对象
         * @param id    播放对象的ID
         * @returns {*} 播放对象
         * @private
         */
        const _getPlayContentById = (id) => {
            for( let i = 0; i < PlaybackList.length; i++ ){
                if( id === PlaybackList[i].id ) return PlaybackList[i];
            }
        };

        /**
         * 通过 当前播放对象的ID来获取下一个即将播放对象的ID,如果已经是最后一个,则返回false
         * @param playList
         * @param playedId
         * @returns {boolean} 即将播放对象的ID
         * @private
         */
        const _getNextPlayId = (playList, playedId) => {
            for( let i = 0; i < playList.length ; i++ ){
                if( playedId === playList[i].id ) return playList[i+1] ? playList[i+1].id : false;
            }
            return false;
        };

        /**
         * 生成一个圆形进度条展示当前播放对象的播放进度
         * @private
         */
        const _initCirclePercent = () => {
            PlayPercent = new ProgressBar.Circle(zhxMediaReviewPercent,{
                // color: '#2196F3',
                strokeWidth: 10,
                trailWidth: 5,
                trailColor : 'rgba(255,255,255,.4)',
                easing: 'linear',
                from: { color: '#2196F3' },
                to: { color: '#8BC34A' },
                // Set default step function for all animate calls
                step: function(state, circle) {
                    circle.path.setAttribute('stroke', state.color);
                }
            });
        };

        /**
         * 开始播放列表内容
         * @param playList {Array}  播放列表
         * @param playId   {string} 即将播放的播放对象的ID
         * @private
         */
        const _startToPlayList = (playList,playId) => {
            //播放完毕后该值为false
            if( !playId ){
                $scope.playEnd = true;
                PlayPercent && PlayPercent.set(0);
                ( $scope.playEnd && PlayPercent ) && $scope.$digest();
                return;
            }
            const playContent = _getPlayContentById(playId);
            switch (playContent.type) {
                case "video":
                    _playVideo(playContent,PlayArea);
                    break;
                case "image":
                    _playImage(playContent,PlayArea);
                    break;
                case "imageArray":
                    _playArrayOfImage(playContent,PlayArea);
                    break;
            }
        };


        /**
         * 创建一个基于videoJS的视频播放器并播放视频
         * 结束时广播播放结束;
         * @param playContent {Object}  即将播放的对象
         * @param PlayArea  {Object}    播放区域 DOM对象
         * @private
         */
        const _playVideo = (playContent,PlayArea) => {
            const id = playContent.id,
                  videoUrl = playContent.url;

            const playAreaWidth = PlayArea.outerWidth(),
                  playAreaHeight = PlayArea.outerHeight();

            let videoPlayerDom = angular.element(`<video id=${id} class="zhx-videojs-player" preload="auto" muted>
                                                    <source src=${videoUrl} type="video/mp4"></source>
                                                  </video>`);
            videoPlayerDom.appendTo(PlayArea);
            videoPlayerDom.css({
                width : playAreaWidth,
                height : playAreaHeight
            });

            //绑定videojs component
            videojs(id,{}, function onPlayerReady(){
                //播放前进行进度重置
                PlayPercent.set(0);
                //start to play
                this.play();

                this.on('playing',()=>{
                    let duration = this.duration();
                    let remaining = this.remainingTime();
                    //这里的播放时间需要照顾网络不好的情况,
                    PlayPercent.animate(1,{
                        duration : (duration - (duration - remaining)) * 1000
                    });
                });
                //任何导致视频暂停时都要停止进度
                this.on('waiting',()=>{
                    PlayPercent.stop();
                });
                //event
                this.on('ended', ()=>{
                    //set playObject props played ==> true
                    playContent.setPlayStatus(true);
                    //start to play next;
                    _startToPlayList(PlaybackList, _getNextPlayId(PlaybackList,id) );
                    //remove been played content;
                    this.dispose();
                })
            });

        };

        /**
         * 创建一个图像的延迟播放,
         * 结束时广播播放结束
         * @param playContent {Object}  即将播放的对象
         * @param PlayArea  {Object}    播放区域 DOM对象
         * @private
         */
        const _playImage = (playContent,PlayArea) => {
            const imgId = playContent.id,
                  imgUrl = playContent.url,
                  imgPlaybackTime = playContent.playTime;

            const playAreaWidth = PlayArea.outerWidth(),
                  playAreaHeight = PlayArea.outerHeight();

            let imgDom = angular.element(`<img id=${imgId} src=${imgUrl} />`);
                imgDom.css({
                    width : playAreaWidth,
                    height : playAreaHeight
                });
            imgDom.appendTo(PlayArea);
            //图片载入完成再开始播放与计时
            imgDom[0].onload = () =>{

                $timeout(()=>{
                    //播放前进行进度重置
                    PlayPercent.set(0);
                    //开始进度播控
                    PlayPercent.animate(1,{
                        duration : imgPlaybackTime * 1000
                    });
                });

                /**
                 * 使用延迟来展示播放时长
                 */
                $timeout(() =>{
                    //set playObject props played ==> true
                    playContent.setPlayStatus(true);
                    //start to play next;
                    _startToPlayList(PlaybackList, _getNextPlayId(PlaybackList,imgId) );
                    $timeout(()=>{
                        //remove been played content;
                        angular.element(`#${imgId}`).remove();
                    },50);

                }, imgPlaybackTime * 1000);

            };

        };

        /**
         * 创建一个 组图的动效延迟播放,
         * 结束时广播播放结束
         * @param playContent {Object}  即将播放的对象
         * @param PlayArea  {Object}    播放区域 DOM对象
         * @private
         */
        const _playArrayOfImage = (playContent,PlayArea) => {
            const contentId = playContent.id,
                  imgArrId = playContent.id,
                  imagesArray = playContent.images;
            //生成组图父DOM
            let slider = angular.element(`<div id=${contentId} class="zhx-flux-play-slider"></div>`);
            //初始化当前已播放的数量
            let playedCount = 0;
            //播放区域大小
            const playAreaWidth = PlayArea.outerWidth(),
                  playAreaHeight = PlayArea.outerHeight();
            //如果播放到最后一个,则会执行该方法结束组图的播放并开始播放playList中的下一个内容
            const _playNextContent = () => {
                playContent.setPlayStatus(true);
                //start to play next;
                _startToPlayList(PlaybackList, _getNextPlayId(PlaybackList,contentId) );
                $timeout(()=>{
                    //remove been played content;
                    slider.remove();
                },0);
            };

            /**
             * 每次过渡切换动图后重置一个进度圈
             * @param index
             * @private
             */
            const _playPercentCircle = (index) =>{
                //播放前进行进度重置
                PlayPercent.set(0);
                //开始进度播控
                PlayPercent.animate(1,{
                    duration : imagesArray[index].playTime * 1000
                });
            };


            if( imagesArray.length ){
                /**
                 * 在页面生成图片组DOM
                 */
                for( let i = 0; i< imagesArray.length; i++){
                    let imageDom = angular.element(`<img src=${imagesArray[i].url} />`);
                    imageDom.css({
                        width : playAreaWidth,
                        height : playAreaHeight
                    });
                    imageDom.appendTo(slider);
                }
                //这里配置一个图片高宽,保证图片不会因为原尺寸而溢出显示不完整
                slider.find('img').css({
                    width : playAreaWidth,
                    height : playAreaHeight
                });

                slider.appendTo( PlayArea );

                /**
                 * 将图片组初始化为一个flux slider;
                 * @type {flux.slider}
                 */
                window.fluxSlider = new flux.slider(`#${contentId}`, {
                    autoplay : false,
                    controls : false,
                    pagination : false,
                    width : playAreaWidth,
                    height : playAreaHeight
                });

                _playPercentCircle(0);

                /**
                 * 为图片组添加播放延迟;
                 */
                let playInterval = $interval(()=>{

                    let playNextContent = false;

                    /**
                     * 这里检测如果播放到倒数第二张,则就需要停掉当前的interval,
                     * 因为最后一张不需要过度动效;否则最后一张会因为动效而播放两次;
                     */
                    if( playedCount === imagesArray.length - 1 ){
                        $interval.cancel( playInterval );
                        playNextContent = !playNextContent;
                    }

                    if( imagesArray[playedCount] ) _playPercentCircle(playedCount);

                    _playImg(imagesArray[playedCount],playNextContent);

                }, imagesArray[playedCount].playTime * 1000 );

            }

            /**
             * 播放图片动效
             * @param imageObject
             * @param playNextContent
             * @private
             */
            function _playImg(imageObject,playNextContent){
                if( playNextContent ){
                    _playNextContent();
                    return;
                }
                const playTransition = imageObject.transition;
                window.fluxSlider.next( playTransition );
                playedCount++;
            }


        };

        /**
         * 在正确获取播放数据后,需要构建播放数据,在页面生成模板,以及播放位置等操作;
         *
         */
        GetCurrentData.promise.then((data)=>{
            //
            zhxMediaReviewService.setPlaybackList(data.playlist);
            //首先在页面构建模板数据以及播放位置
            _constructTemplateInPage(data).then((templateData)=>{
                //构建播控数据
                PlaybackList = zhxMediaReviewService.getPlaybackList();
                //
                return zhxMediaReviewService.constructPlayList(PlaybackList);
            }).then((data)=>{
                //开始做一些播放准备,并开始播放第一个对象
                const playId = PlaybackList[0].id;
                /**
                 * 初始化播放进度组件
                 */
                _initCirclePercent(PlaybackList[0]);
                /**
                 * 开启播放第一个playback;
                 */
                _startToPlayList(PlaybackList,playId);

            });
        });

        /**
         * 组件初始化后获取外部传来的数据,数据仅获取一次后移除监听;
         * @type {*}
         */
        let clearDataWatch = $scope.$watch('options.data',(data)=>{
            if( data ){
                GetCurrentData.resolve(data.data);
                clearDataWatch();
            }
        });

        /**
         * 重播
         */
        $scope.replay = () => {
            $scope.playEnd = false;
            PlayPercent && PlayPercent.set(0);
            _startToPlayList(PlaybackList, PlaybackList[0].id );
        };

    }]);